﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

/*
 * Służy do wizualizacji brył otaczających AABB.
 * Tworzy listę wierzchołków, które służą do narysowania AABB.
 * Wierzchołki są obliczone dla sześcianu o wymiarach = 1.
 * Bryła zostaje przeskalowana dopiero przy renderowaniu.
 */
namespace Projekt.Models.Primitives
{
    public static class BoundingBoxRender
    {
        static BasicEffect basicEffect;
        // Tablica przechowująca dane wierzchołków dla bryły
        static VertexPositionColor[] vertices;

        /// <summary>
        /// Inicjalizacja wierzchołków.
        /// Jeśli nie wywołano wcześniej, zostanie uruchomiona w momencie pierwszego użycia
        /// </summary>
        /// <param name="graphicsDevice"></param>
        public static void Initialize(GraphicsDevice graphicsDevice)
        {
            basicEffect = new BasicEffect(graphicsDevice);
            basicEffect.VertexColorEnabled = true;

            vertices = new VertexPositionColor[20];
            // Wypełniamy tablicę odpowiednio ustawionymi wierzchołkami.
            // Nie potrzeba nam ścian bocznych skoro jest to tylko siatka
            //front
            vertices[0].Position = new Vector3(-0.5f, 0.5f, 0.5f);
            vertices[0].Color = Color.White;
            vertices[1].Position = new Vector3(0.5f, 0.5f, 0.5f);
            vertices[1].Color = Color.White;
            vertices[2].Position = new Vector3(0.5f, -0.5f, 0.5f);
            vertices[2].Color = Color.White;
            vertices[3].Position = new Vector3(-0.5f, -0.5f, 0.5f);
            vertices[3].Color = Color.White;
            vertices[4].Position = new Vector3(-0.5f, 0.5f, 0.5f);
            vertices[4].Color = Color.White;

            //back
            vertices[5].Position = new Vector3(-0.5f, 0.5f, -0.5f);
            vertices[5].Color = Color.White;
            vertices[6].Position = new Vector3(0.5f, 0.5f, -0.5f);
            vertices[6].Color = Color.White;
            vertices[7].Position = new Vector3(0.5f, -0.5f, -0.5f);
            vertices[7].Color = Color.White;
            vertices[8].Position = new Vector3(-0.5f, -0.5f, -0.5f);
            vertices[8].Color = Color.White;
            vertices[9].Position = new Vector3(-0.5f, 0.5f, -0.5f);
            vertices[9].Color = Color.White;

            //top
            vertices[10].Position = new Vector3(-0.5f, 0.5f, 0.5f);
            vertices[10].Color = Color.White;
            vertices[11].Position = new Vector3(0.5f, 0.5f, 0.5f);
            vertices[11].Color = Color.White;
            vertices[12].Position = new Vector3(0.5f, 0.5f, -0.5f);
            vertices[12].Color = Color.White;
            vertices[13].Position = new Vector3(-0.5f, 0.5f, -0.5f);
            vertices[13].Color = Color.White;
            vertices[14].Position = new Vector3(-0.5f, 0.5f, 0.5f);
            vertices[14].Color = Color.White;

            //bottom
            vertices[15].Position = new Vector3(-0.5f, -0.5f, 0.5f);
            vertices[15].Color = Color.White;
            vertices[16].Position = new Vector3(0.5f, -0.5f, 0.5f);
            vertices[16].Color = Color.White;
            vertices[17].Position = new Vector3(0.5f, -0.5f, -0.5f);
            vertices[17].Color = Color.White;
            vertices[18].Position = new Vector3(-0.5f, -0.5f, -0.5f);
            vertices[18].Color = Color.White;
            vertices[19].Position = new Vector3(-0.5f, -0.5f, 0.5f);
            vertices[19].Color = Color.White;
        }

        /// <summary>
        /// Wyświetla bryłę AABB o podanym kolorze
        /// </summary>
        /// <param name="sphere">Bryła otaczająca do wyświetlenia</param>
        /// <param name="graphicsDevice"></param>
        /// <param name="View">Macierz widoku</param>
        /// <param name="Projection">Macierz projekcji</param>
        /// <param name="color">Kolor bryły</param>
        public static void Render(BoundingBox box, GraphicsDevice graphicsDevice, Matrix View, Matrix Projection, Color color)
        {
            if (basicEffect == null) Initialize(graphicsDevice);

            basicEffect.Projection = Projection;
            basicEffect.View = View;
            // Obliczanie macierzy transformacji dla bryły.
            // Tutaj bryła jest przesuwana i przeskalowana.
            basicEffect.World = Matrix.CreateScale(new Vector3(box.Max.X - box.Min.X, box.Max.Y - box.Min.Y, box.Max.Z - box.Min.Z)) * Matrix.CreateTranslation(box.Min + (box.Max - box.Min) / 2f);
            // Ustalenie koloru dla krawędzi bryły.
            basicEffect.DiffuseColor = color.ToVector3();
            basicEffect.CurrentTechnique.Passes[0].Apply();
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices, 0, 4);
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices, 5, 4);
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices, 10, 4);
            graphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices, 15, 4);
        }

    }
}
